package org.example.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.example.Constants;
import org.example.LoginRequestPacket;
import org.example.MessageRequestPacket;
import org.example.Spliter;
import org.example.codec.PacketDecoder;
import org.example.codec.PacketEncoder;
import org.example.concole.ConsoleCommandManager;
import org.example.concole.LoginConsoleCommand;
import org.example.concole.LogoutConsoleCommand;
import org.example.im.SessionUtil;

import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;


// pipeline 多处理器处理解耦代码
public class ClientBoostrap {
    public static void main(String[] args) {
        // 客户端引导器
        Bootstrap bootstrap = new Bootstrap();

        // 线程组
        NioEventLoopGroup eventExecutors = new NioEventLoopGroup();

        // 绑定
        bootstrap
                // 线程模型
                .group(eventExecutors)
                // IO 模型
                .channel(NioSocketChannel.class)
                //.option(ChannelOption.SO_KEEPALIVE, true)
                // 处理器
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel ch) throws Exception {
                        ch.pipeline().addLast(new Spliter());
                        ch.pipeline().addLast(new PacketDecoder());
                        ch.pipeline().addLast(new LoginResponseHandler());
                        // 客户端：创建群组响应指令处理器
                        ch.pipeline().addLast(new CreateGroupResponseHandler());
                        ch.pipeline().addLast(new JoinGroupResponseHandler());
                        ch.pipeline().addLast(new QuitGroupResponseHandler());
                        ch.pipeline().addLast(new MemberGroupResponseHandler());
                        ch.pipeline().addLast(new MessageResponseHandler());
                        ch.pipeline().addLast(new PacketEncoder());
                    }
                });

        conn(bootstrap, Constants.port, Constants.MAX_RETRY);
    }


    private static void conn(Bootstrap bootstrap, int port, int maxRetry) {
        bootstrap.connect(Constants.host, port).addListener(future -> {
            if (future.isSuccess()) {
                System.out.println("连接服务端成功，端口:" + port);
                startThread(((ChannelFuture) future).channel());
            } else if (maxRetry == 0) {
                System.out.println("连接服务端失败，重连次数过多。停止重试。");
            } else {
                System.out.println(new Date() + "连接服务端失败，端口:" + port + "。开始重连...");

                // 第几次重连的
                int order = Constants.MAX_RETRY - maxRetry + 1;
                // 下一次的间隔
                int delay = 1 << order;

                bootstrap.config().group().schedule(() -> {
                    conn(bootstrap, port, maxRetry - 1);
                }, delay, TimeUnit.SECONDS);

            }
        });
    }

    private static void startThread(Channel channel) {
        ConsoleCommandManager consoleCommandManager = new ConsoleCommandManager();
        LoginConsoleCommand loginConsoleCommand = new LoginConsoleCommand();
        new Thread(() -> {
            while (!Thread.interrupted()) {
                Scanner scanner = new Scanner(System.in);
                try {
                    Thread.sleep(2000);
                    if (SessionUtil.hasLogin(channel)) {
                        // 已经登录，可以进行单聊、群聊的操作
                        consoleCommandManager.exec(scanner, channel);
                    }else{
                        // 没有登录走登录的逻辑
                        loginConsoleCommand.exec(scanner, channel);
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        }).start();
    }
}
